Git stash: lưu tạm công việc dở và khôi phục đúng lúc

Nội dung

Git stash cho phép lưu tạm các thay đổi chưa commit để chuyển sang task khác, rồi khôi phục lại đúng lúc — tránh commit dở hoặc mất công việc đang làm.

Tóm tắt nhanh

  • git stash lưu tạm toàn bộ thay đổi chưa commit vào một “ngăn kéo” riêng, trả working directory về trạng thái sạch.
  • Dùng pop hoặc apply để lấy lại; pop xóa bản lưu sau khi áp, apply giữ lại.
  • Có thể đặt tên bản lưu (save "tên"), xem danh sách (list), hoặc xóa (drop/clear).
  • Mặc định không lưu untracked files; cần thêm -u hoặc -a nếu muốn bao gồm.
  • Có thể tạo nhánh mới trực tiếp bằng git stash branch — giải pháp an toàn khi bị xung đột mã nguồn.

Bạn đang làm dở một feature phức tạp, code đang lủng củng giữa chừng — thì Product Manager gửi Slack: “Fix bug này gấp, ảnh hưởng khách hàng!”. Nếu commit lúc này thì lịch sử git sẽ có một commit rác. Nếu không commit thì không chuyển nhánh được. Đây chính xác là tình huống git stash được sinh ra để giải quyết.

git stash lưu tạm công việc và khôi phục
Git stash: lưu tạm công việc đang làm để chuyển task gấp, không mất một dòng code nào

Git stash là gì và khi nào cần dùng?

Git stash là lệnh lưu tạm toàn bộ thay đổi chưa commit vào một stack riêng, trả working directory về trạng thái sạch (HEAD), giúp bạn chuyển task mà không cần commit vội.

Về bản chất, cơ chế này hoạt động như một “ngăn kéo” — bạn nhét mọi thứ đang dở vào đó, làm việc khác xong rồi lấy ra tiếp tục. Không có giới hạn số lượng mục lưu trữ, và mọi thứ được quản lý theo dạng LIFO (Last In, First Out) — phần tử mới nhất luôn ở trên cùng.

Git stash
Lệnh lưu tạm thay đổi chưa commit (cả staged lẫn unstaged) vào một stack riêng biệt với lịch sử commit, cho phép working directory trở về trạng thái HEAD sạch.

Các tình huống thực tế thường gặp:

  • Đang làm feature A, có bug khẩn cấp cần fix trên nhánh khác
  • Muốn kéo mã nguồn mới nhất từ remote nhưng đang có thay đổi chưa xong
  • Cần test một cách làm khác mà không muốn mất code hiện tại
  • Lỡ bắt đầu làm trên nhánh sai, cần chuyển sang nhánh đúng
Các tình huống cần dùng git stash
Bốn tình huống phổ biến cần dùng git stash trong workflow hàng ngày

Cách dùng cơ bản: save, pop, apply

Ba thao tác cốt lõi gồm lưu (save), lấy ra và xóa khỏi ngăn chứa (pop), hoặc lấy ra nhưng giữ lại bản lưu (apply).

Giả sử bạn đang làm dở feature trên nhánh feature/login:

# Kiểm tra trạng thái hiện tại
git status
# On branch feature/login
# Changes not staged for commit:
#   modified: src/auth/login.js
# Untracked files:
#   src/auth/oauth.js

# Lưu tạm toàn bộ thay đổi
git stash
# Saved working directory and index state WIP on feature/login: a3f2b1c Add base login form

# Working directory đã sạch — có thể chuyển nhánh
git checkout main
git checkout -b hotfix/payment-null-check
# ... fix bug, commit, push ...

# Quay lại nhánh cũ và lấy code ra
git checkout feature/login
git stash pop
# On branch feature/login
# Changes not staged for commit:
#   modified: src/auth/login.js

Khác biệt giữa pop và apply:

  • pop: Áp thay đổi vào working directory xóa khỏi ngăn chứa. Dùng khi chắc chắn không cần dùng lại bản này.
  • apply: Áp thay đổi nhưng giữ nguyên trong ngăn chứa. Rất tiện khi muốn áp cùng một đoạn code thử nghiệm vào nhiều nhánh khác nhau.
# Apply nhưng giữ lại bản lưu
git stash apply

# Hoặc chỉ định bản lưu cụ thể
git stash apply stash@{2}

Bạn cũng có thể gắn kèm mô tả rõ ràng để dễ nhận biết sau này:

git stash save "WIP: login form với OAuth2 flow"
# hoặc cú pháp mới hơn:
git stash push -m "WIP: login form với OAuth2 flow"

Bạn đang đọc bài viết thuộc chuyên mục Lập trình của VietnamTutor — nơi mình chia sẻ kinh nghiệm thực chiến về Git, DevOps và workflow lập trình hàng ngày.

Quy trình git stash save và pop cơ bản
Vòng lặp git stash cơ bản: lưu tạm → chuyển sang task khác → khôi phục lại

Quản lý nhiều bản lưu: list, show, drop

Hệ thống cho phép lưu trữ nhiều mục cùng lúc; dùng git stash list để kiểm tra toàn bộ, git stash show để xem chi tiết, và git stash drop hoặc git stash clear để dọn dẹp.

# Xem danh sách tất cả stash
git stash list
# stash@{0}: On feature/login: WIP: login form với OAuth2 flow
# stash@{1}: WIP on feature/dashboard: add chart component
# stash@{2}: WIP on main: quick experiment

# Xem tóm tắt những gì có trong stash@{1}
git stash show stash@{1}

# Xem diff đầy đủ của stash@{1}
git stash show -p stash@{1}

# Áp một stash cụ thể
git stash apply stash@{1}

# Xóa một stash cụ thể
git stash drop stash@{2}

# Xóa toàn bộ stash (cẩn thận!)
git stash clear

Lưu ý quan trọng về indexing stash: Mỗi khi bạn stash mới, index sẽ dịch chuyển. Stash cũ nhất không phải lúc nào cũng là stash@{0} sau khi thêm stash mới. Hãy luôn chạy git stash list trước khi apply để tránh áp nhầm.

Danh sách git stash với nhiều entries
Quản lý nhiều stash bằng git stash list và git stash show để không bị lẫn lộn

Xử lý untracked và ignored files

Mặc định, công cụ chỉ lưu các tệp đã được theo dõi (staged hoặc modified). Để lưu thêm các tệp chưa theo dõi (untracked files), hãy thêm cờ -u; để bao gồm toàn bộ tệp bị bỏ qua (ignored), dùng -a.

# Chỉ lưu tracked files (mặc định)
git stash

# Lưu cả untracked files (file mới chưa git add)
git stash -u
# hoặc
git stash --include-untracked

# Lưu tất cả kể cả ignored files (dùng cẩn thận)
git stash -a
# hoặc
git stash --all

Trong thực tế, -u là tùy chọn cần thiết nhất. Ví dụ: bạn tạo file src/auth/oauth.js mới nhưng chưa git add — nếu không dùng -u, file này sẽ không được cất đi và vẫn còn trong working directory sau khi chuyển nhánh.

Trường hợp cất tạm một phần file (partial stash):

# Interactive: chọn từng hunk để lưu
git stash -p
# hoặc
git stash --patch

# Chỉ lưu một file cụ thể
git stash push -m "only login.js" -- src/auth/login.js

Tính năng lưu theo phần rất hữu ích khi bạn muốn commit một phần thay đổi nhưng giữ lại phần còn lại để làm tiếp sau. Tham số -p hoạt động tương tự git add -p, cho phép xem lại từng đoạn mã.

Xem thêm các lệnh Git liên quan: git commit nhầm file — cách sửa an toàngit reset vs revert vs restore: chọn lệnh đúng.

Tạo nhánh từ bản lưu khi bị xung đột

Khi khôi phục vào nhánh mà mã nguồn đã thay đổi nhiều, có thể xảy ra xung đột. Giải pháp an toàn nhất là tạo nhánh mới trực tiếp bằng cú pháp git stash branch <tên-nhánh>.

# Tạo nhánh mới từ stash@{0} (mặc định là bản mới nhất)
git stash branch feature/login-v2

# Hoặc từ bản lưu cụ thể
git stash branch feature/dashboard-chart stash@{1}

Lệnh này tự động thực hiện:

  1. Chuyển về commit mà tại đó bản lưu được tạo ra
  2. Tạo một nhánh mới độc lập từ điểm đó
  3. Áp toàn bộ thay đổi vào nhánh mới
  4. Xóa bản lưu khỏi ngăn chứa nếu áp thành công

Đây là phương pháp giải quyết tối ưu khi bản cất giữ đã quá cũ và mã nguồn cơ sở đã khác biệt nhiều. Thay vì phải xử lý xung đột phức tạp, bạn có một nhánh riêng với điểm bắt đầu chính xác — rất dễ đánh giá và tích hợp sau này.

Git stash branch giải quyết conflict
git stash branch tạo nhánh từ đúng commit gốc, tránh conflict khi base code đã thay đổi nhiều

Tip thực chiến: dùng stash đúng cách

Lệnh lưu tạm này chỉ là công cụ hỗ trợ ngắn hạn, không phải giải pháp sao lưu lâu dài. Luôn đặt thông điệp rõ ràng, kiểm tra danh sách thường xuyên và dọn dẹp các mục cũ để tránh nhầm lẫn.

Tip 1: Luôn đặt tên khi lưu

# Không nên (khó nhớ sau vài ngày)
git stash

# Nên (mô tả rõ đang làm gì)
git stash push -m "WIP: refactor auth middleware — chưa xong phần token refresh"

Tip 2: Không lưu trữ quá lâu

Dữ liệu tạm không đồng bộ lên máy chủ từ xa — nếu máy tính gặp sự cố, công việc chưa commit sẽ mất. Nếu một thay đổi cần giữ qua nhiều ngày, hãy tạo nhánh WIP riêng. Theo thống kê từ các nhóm kỹ sư phần mềm [1], việc cất giữ tạm thời lý tưởng chỉ nên tồn tại trong phạm vi một buổi làm việc.

Tip 3: Xem trước thay đổi khi khôi phục

# Luôn kiểm tra nội dung trước khi pop
git stash show -p stash@{0}

# Sau đó mới pop
git stash pop

Tip 4: Dọn dẹp dữ liệu cũ định kỳ

# Xem stash nào cũ/không cần nữa
git stash list

# Xóa stash cụ thể
git stash drop stash@{3}

# Hoặc xóa tất cả (đảm bảo không cần trước khi clear)
git stash clear

Tip 5: Kết hợp với alias rút gọn

# Thêm vào ~/.gitconfig để dùng nhanh
git config --global alias.ss 'stash save'
git config --global alias.sl 'stash list'
git config --global alias.sp 'stash pop'

# Sau đó dùng:
git ss "WIP: login form"
git sl
git sp
Best practices khi dùng git stash
5 quy tắc dùng git stash đúng cách trong môi trường làm việc chuyên nghiệp

Nguồn tham khảo

  1. Git Official Documentation — git-stash
  2. Atlassian Git Tutorials — Git stash
  3. Stack Overflow — Recover stashed changes after accidental drop
  4. Julia Evans — Inside .git (2024)
  5. Oh Shit, Git!? — Common Git mistakes and fixes

Các câu hỏi thường gặp

Lệnh này có lưu các file đã staged không?

Có. Mặc định hệ thống lưu cả staged lẫn unstaged changes. Nếu chỉ muốn cất phần unstaged và giữ nguyên staging area, hãy dùng thêm tùy chọn --keep-index.

Làm sao khôi phục bản lưu đã bị drop nhầm?

Git vẫn giữ các đối tượng commit tạm trong một thời gian trước khi garbage collect. Bạn có thể chạy git fsck --no-reflogs | grep commit để tìm dangling commits, sau đó dùng git stash apply <hash> để lấy lại dữ liệu.

Dữ liệu lưu tạm có đồng bộ lên remote repository không?

Không. Toàn bộ ngăn chứa chỉ tồn tại cục bộ trên máy cá nhân. Nếu cần chia sẻ tiến độ với đồng nghiệp hoặc sao lưu an toàn, hãy đẩy lên một nhánh WIP riêng.

Sự khác biệt giữa pop và apply là gì?

pop áp bản lưu vào thư mục làm việc rồi xóa bản đó khỏi ngăn chứa. Trong khi đó, apply giữ nguyên bản lưu để có thể tái sử dụng trên các nhánh khác.

Có thể bị xung đột khi khôi phục code không?

Có. Nếu nhánh hiện tại đã thay đổi trùng với các dòng trong bản lưu, Git sẽ báo conflict. Giải pháp an toàn nhất là dùng lệnh git stash branch <tên-nhánh> để tạo nhánh trực tiếp từ đúng commit gốc.

Khi nào nên lưu tạm, khi nào nên commit WIP?

Hãy lưu tạm khi cần chuyển việc nhanh trong vài tiếng của ca làm. Nếu cần giữ qua đêm hoặc phối hợp nhóm, tạo nhánh WIP có commit rõ ràng sẽ an toàn và minh bạch hơn.

Nếu bạn đang gặp vấn đề với Git workflow, VietnamTutor có thể hỗ trợ thiết lập quy trình làm việc chuẩn cho team — từ branching strategy, code review process đến CI/CD automation. Liên hệ để được tư vấn miễn phí.

Tú Anh

Cây bút chính tại VietnamTutor

Bài viết cùng chuyên mục

Vibe coding và nợ kỹ thuật thầm lặng: kiểm soát bằng kỹ thuật ngữ cảnh

Vibe coding tăng tốc nhưng âm thầm tích lũy nợ kỹ thuật. Bài này giải thích vì sao và cách context engineering giúp bạn giữ codebase

Git rebase bị conflict: cách sửa hoặc abort an toàn

Hướng dẫn xử lý git rebase bị conflict: cách kiểm tra file lỗi, sửa conflict marker, tiếp tục rebase, abort an toàn và khi nào không

Bảo mật vibe coding: đừng để AI sinh lỗ hổng website

Bảo mật vibe coding không chỉ là quét lỗi sau khi AI viết code. Bài viết đưa ra checklist kiểm soát secret, prompt injection, dependency, auth

Kiểm thử code do AI tạo: danh sách kiểm tra trước khi deploy

Code do AI tạo cần được kiểm thử theo nhiều lớp trước khi lên website thật. Checklist này giúp bạn kiểm tra chức năng, bảo mật,

Lỡ push .env lên Git: cách xử lý secret bị lộ

Lỡ push .env lên Git không chỉ là lỗi xóa file. Hãy revoke hoặc rotate secret trước, rồi dọn Git history và ngăn sự cố lặp

Quy trình vibe coding 7 bước: từ ý tưởng đến prototype

Quy trình vibe coding hiệu quả bắt đầu từ giả thuyết kinh doanh, không phải prompt dài. Bài viết hướng dẫn 7 bước từ brief, dữ

Vibe coding cho doanh nghiệp: việc nào nên làm bằng AI?

Vibe coding cho doanh nghiệp hữu ích khi cần thử prototype, dashboard hoặc automation nhỏ. Bài viết giúp bạn phân loại use case theo mức rủi

AI viết code nhanh hơn review: kiểm soát thế nào?

Khi AI viết code nhanh hơn khả năng review của team, doanh nghiệp cần đổi cách kiểm soát chất lượng. Bài viết đưa ra framework thực

Git detached HEAD là gì? Cách thoát an toàn

Bài viết này giải thích detached HEAD trong Git, cách nhận biết trạng thái này và các bước thoát ra an toàn mà không mất code.

Rủi ro vibe coding: 9 lỗi khiến prototype khó vận hành

Bài viết này chỉ ra 9 rủi ro phổ biến khi vibe coding và cách kiểm soát để prototype không biến thành gánh nặng vận hành.

Vibe coding là gì? Cách thử ý tưởng phần mềm bằng AI

Vibe coding giúp chủ doanh nghiệp biến ý tưởng phần mềm thành prototype nhanh hơn bằng AI. Bài viết này chỉ ra khi nào nên thử,

GitHub Actions CI/CD: quy trình deploy website an toàn

Hướng dẫn xây pipeline GitHub Actions CI/CD cho website: build, test, cache dependency, đóng artifact, deploy staging/production và quản lý secret an toàn.