Chuyển đến nội dung chính
Git

Giải thích Git Stash: Lưu, khôi phục và quản lý thay đổi

Tìm hiểu cách dùng git stash để lưu, kiểm tra, khôi phục và quản lý thay đổi. Hiểu stash có chọn lọc, cách xử lý xung đột và thực hành tốt cho quy trình làm việc gọn gàng.
Allan Ouko's photo
Allan Ouko
Đã cập nhật · 9 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Tạo tài khoản miễn phí của bạn

Luyện tập và Lộ trình tiến trình của bạn.

Tiếp Tục Với Google
Bằng cách tiếp tục, bạn chấp nhận Điều khoản sử dụng, Chính sách bảo mật và việc dữ liệu của bạn được lưu trữ tại Hoa Kỳ.

Bạn đang dở tay triển khai một tính năng mới trong pipeline dữ liệu thì nhận được báo cáo lỗi khẩn cấp. Thư mục làm việc của bạn đầy những thay đổi còn dang dở. Bạn chưa sẵn sàng để commit, nhưng cần chuyển nhánh ngay lập tức.

Trong hướng dẫn này, tôi sẽ chỉ bạn cách sử dụng đầy đủ bộ lệnh git stash. Bạn sẽ học cách lưu, kiểm tra, khôi phục, stash có chọn lọc và dọn dẹp các stash trong Git. Để học thêm, tôi khuyến nghị bạn tham gia khóa Giới thiệu về các khái niệm GitHub của chúng tôi để tìm hiểu thêm về quản lý phiên bản và làm việc với kho trên GitHub.

Git stash là gì?

git stash là một lệnh Git tạm thời cất các thay đổi chưa commit để bạn có thể quay về một thư mục làm việc sạch, mà không cần tạo commit Git. Điều này giúp bạn dễ dàng chuyển nhánh hoặc xử lý công việc khẩn mà không mất tiến độ.

Các stash được lưu theo cấu trúc ngăn xếp LIFO (vào sau ra trước). Stash mới nhất luôn là stash@{0}, tiếp theo là stash@{1}, v.v.

Mặc định, git stash lưu các tệp đã được theo dõi có chỉnh sửa và các thay đổi đã stage (trong index). Tuy nhiên, nó không bao gồm các tệp mới chưa được theo dõi và các tệp bị bỏ qua như trong .gitignore.

Cách lưu thay đổi với git stash

Trong phần này, tôi sẽ hướng dẫn bạn ba cách phổ biến để stash thay đổi. Ta sẽ dùng cùng một bối cảnh: giả sử bạn đang làm việc trên một dự án pipeline dữ liệu với các tệp data_pipeline.py, config.yaml và tests/test_pipeline.py.

Stash các thay đổi đã theo dõi

Vì git stash lưu các thay đổi đã chỉnh sửa hoặc đã stage, hãy chạy git status để kiểm tra trạng thái các tệp trong thư mục làm việc. Sau khi chạy git stash, cả thay đổi đã stage và chưa stage trên các tệp đã theo dõi đều được lưu, để lại cho bạn một thư mục làm việc sạch.

Cách dùng git stash để stash các thay đổi đã theo dõi.

Bao gồm thay đổi chưa theo dõi và tệp mới

Theo mặc định, git stash bỏ qua các tệp chưa từng được thêm vào kho. Nếu bạn tạo một tệp kiểm thử mới, một stash tiêu chuẩn sẽ để nó lại trong thư mục của bạn, điều này có thể gây rắc rối khi chuyển nhánh.

Cách dùng git status để kiểm tra trạng thái hiện tại của thư mục làm việc.

Nếu bạn chạy git stash, tệp đó sẽ vẫn còn. Để bao gồm nó, dùng lệnh -u hoặc --include-untracked:

git stash -u

Cách bao gồm thay đổi chưa theo dõi và tệp mới bằng git stash.

Để bao gồm mọi tệp, kể cả những tệp bị bỏ qua theo .gitignore, bạn có thể dùng git stash --all hoặc -a. Tuy nhiên, hãy cẩn thận vì điều này có thể vô tình gom cả các tệp như log hoặc artifact build.

Đặt tên cho stash

Khi dùng git stash, các thông điệp mặc định như WIP on main sẽ gây nhầm lẫn nếu bạn có nhiều stash. Để tránh điều này, hãy luôn thêm một thông điệp mô tả khi bạn muốn push các stash. 

git stash push -m "refactor pipeline config handling."

Bạn có thể dùng lệnh git stash list để xem và so sánh danh sách stash. Hãy để ý sự khác biệt giữa stash có tên và stash mặc định.

Cách đặt tên cho một stash bằng thông điệp mô tả.

Dùng thông điệp rõ ràng giúp bạn dễ xác định stash phù hợp hơn sau này, đặc biệt khi phải xử lý nhiều tác vụ hoặc cộng tác nhóm.

Tôi khuyến nghị bạn thử GitHub Foundations và Git Fundamentals để học quản lý phiên bản với Git từ cơ bản đến quy trình nâng cao, bao gồm theo dõi thay đổi, quản lý kho và cộng tác hiệu quả. 

Cách xem và kiểm tra các stash

Trước khi áp dụng một stash một cách mù quáng, điều quan trọng là xác minh bên trong có gì. Bước này thường bị bỏ qua, nhưng nó giúp tránh nhầm lẫn hoặc ghi đè ngoài ý muốn.

git stash list: Liệt kê tất cả stash

Dùng lệnh dưới đây để xem ngăn xếp stash của bạn:

git stash list

Cách liệt kê tất cả các stash bằng git stash list.

Giờ bạn đã biết các stash theo thứ tự LIFO (vào sau ra trước). Stash mới nhất luôn là stash@{0}, và mỗi stash mới sẽ đẩy các stash cũ xuống dưới.

git stash show: Kiểm tra stash trước khi áp dụng

Để có bản tóm tắt nhanh về các thay đổi trong một stash, bạn có thể dùng lệnh show trên một stash cụ thể. Ví dụ, lệnh dưới đây hiển thị các thay đổi trong stash mới nhất:

git stash show stash@{0}

Cách kiểm tra một stash trước khi áp dụng thay đổi.

Để xem các thay đổi mã thực tế (full diff), dùng lệnh dưới đây để hiển thị tất cả thay đổi theo từng dòng được lưu trong stash đó.

git stash show -p stash@{0}

Cách kiểm tra các thay đổi mã thực tế của một stash trước khi áp dụng.

Theo thực hành tốt, hãy luôn kiểm tra một stash trước khi áp dụng, đặc biệt nếu nó đã vài ngày tuổi hoặc bạn không chắc nó chứa gì.

Cách khôi phục các thay đổi đã stash

Khi đã lưu công việc bằng git stash, bạn sẽ cần cách đưa chúng trở lại. Có hai phương pháp chính để khôi phục stash, bao gồm cách nhắm tới một stash cụ thể theo chỉ số của nó.

git stash pop: áp dụng và xóa

Đây là cách phổ biến nhất để khôi phục một stash. Nó lấy stash trên cùng (stash@{0}), áp dụng các thay đổi vào nhánh hiện tại của bạn, rồi xóa stash đó khỏi ngăn xếp.

git stash pop

Cách khôi phục và loại bỏ một stash bằng git stash pop.

Sau khi chạy pop, thay đổi của bạn được khôi phục và stash bị xóa. Vì vậy, hãy dùng pop khi bạn chắc chắn đã xong với trạng thái đã lưu đó và muốn giữ danh sách stash gọn gàng.

Để hiểu sâu hơn về lệnh pop, tôi khuyến nghị xem hướng dẫn Git Stash Pop để học cách lưu công việc chưa commit khi chuyển nhánh trong repo của bạn.

git stash apply: áp dụng và giữ lại

Nếu bạn muốn khôi phục thay đổi nhưng vẫn giữ stash để dùng lại, hãy dùng lệnh apply như sau:

git stash apply stash@{1}

Cách khôi phục một stash và giữ lại bằng git stash apply.

Lưu ý rằng tham chiếu một stash theo chỉ số stash@{1} sẽ nhắm tới stash cụ thể để khôi phục. Phương pháp này hữu ích khi bạn muốn áp dụng cùng thay đổi trên nhiều nhánh, như một chỉnh sửa cấu hình dùng chung cần đưa vào cả main và staging.

Bạn có thể dùng git stash list để xác nhận stash vẫn còn sau khi dùng lệnh apply.

Cách hiển thị tất cả stash bằng git stash list.

Cách stash có chọn lọc

Trong các dự án thực tế, thay đổi của bạn thường lẫn lộn. Với những tình huống như vậy, bạn có thể muốn chỉ stash một phần công việc, trong khi giữ phần còn lại sẵn sàng. Git cung cấp hai phương pháp để kiểm soát chi tiết.

git stash push -m: Stash các tệp cụ thể

Nếu bạn biết chính xác những tệp nào cần tạm gác, bạn có thể chỉ stash các tệp được chọn bằng cách chỉ định đường dẫn của chúng:

Ví dụ, lệnh dưới đây chỉ stash tệp data_pipeline.py. Điều này hữu ích khi bạn muốn tạm dừng công việc trên một tính năng thử nghiệm trong khi vẫn giữ một bản sửa lỗi đã stage sẵn sàng để commit.

git stash push -m "stash experimental pipeline logic" data_pipeline.py

Để kiểm tra lệnh của bạn đã chạy thành công chưa, dùng git status để xem trạng thái repo trước và sau.

Cách stash các tệp cụ thể bằng Git.

git stash push -p -m: Stash tương tác các hunk cụ thể

Đôi khi bạn có cả mã “tốt” và mã “WIP” trong cùng một tệp. Khi đó, hãy dùng cờ -p hoặc --patch để kích hoạt phiên làm việc tương tác. Điều này cho phép bạn chọn các phần (“hunk”) thay đổi cụ thể trong một tệp.

git stash push -p -m "Selective stash of pipeline logic"

Cách stash tương tác các hunk cụ thể.

Bạn sẽ thấy phần “Stash this hunk” với các lựa chọn sau:

  • y: Đồng ý, stash hunk này

  • n: Không, bỏ qua hunk này

  • q: Thoát; không stash hunk này hoặc các hunk còn lại.

  • a: Tất cả; stash hunk này và tất cả hunk tiếp theo trong tệp.

  • d: Xóa; không stash hunk này hoặc bất kỳ hunk tiếp theo nào trong tệp.

  • ?: trợ giúp

Bạn nên lưu ý quy trình này rất giống với git add -p. Nó hữu ích khi các thay đổi trong cùng một tệp không liên quan và cần xử lý riêng.

Cách dọn dẹp stash

Stash được thiết kế để tồn tại ngắn hạn. Nếu để chúng chất đống, bạn sẽ khó tìm đúng cái về sau và tăng rủi ro xung đột khi cuối cùng áp dụng chúng.

git stash drop: Xóa một stash cụ thể

Để xóa một stash, dùng git stash drop kèm chỉ số của nó. Ví dụ, lệnh dưới đây xóa stash thứ 4 trong danh sách.

git stash drop stash@{3}

Cách xóa một stash cụ thể bằng chỉ số của nó.

Từ ví dụ trên, bạn có thể thấy danh sách stash giảm đi và các stash còn lại được đánh lại chỉ số sau khi xóa.

git stash clear: Xóa tất cả stash

Để xóa tất cả stash cùng lúc, dùng:

git stash clear

Lệnh này không tạo đầu ra khi thành công, và bạn có thể xác minh bằng cách chạy git stash list.

Cách xóa tất cả stash bằng git stash clear.

Tôi khuyến nghị bạn hết sức thận trọng khi dùng git stash clear vì thao tác này là vĩnh viễn và không có hoàn tác tích hợp. Chỉ chạy khi bạn chắc chắn không còn cần bất kỳ công việc đã stash nào.

git stash branch: Chuyển một stash thành nhánh

Nếu nhánh hiện tại của bạn đã phân kỳ đáng kể kể từ khi tạo stash, việc áp dụng nó có thể dẫn đến xung đột hợp nhất. Khi đó, bạn có thể tạo một nhánh mới trực tiếp từ stash:

git stash branch pipeline-fix stash@{1}

Cách chuyển một stash thành nhánh bằng git stash branch.

Lệnh trên thực hiện những việc sau:

  • Tạo một nhánh mới từ commit gốc nơi stash được tạo
  • Áp dụng stash
  • Loại bỏ nó khỏi danh sách stash

Tôi khuyến nghị bạn xem hướng dẫn Git Branch để tìm hiểu thêm về quản lý nhánh nhằm cải thiện phát triển và cộng tác.

Các lệnh Git Stash khác đáng biết

Ngoài các quy trình thường dùng, dưới đây là một số lệnh git stash nâng cao bạn nên biết:

  • git stash create: Tạo một đối tượng stash mà không thêm vào danh sách stash

  • git stash store: Lưu một stash được tạo bằng create

  • git stash export: Xuất một stash sang một tham chiếu hoặc in ra

  • git stash import: Nhập một stash từ một commit hiện có

Lỗi thường gặp và cách khắc phục

Mặc dù git stash khá đơn giản, một vài vấn đề thường gặp vẫn có thể làm bạn vấp. Dưới đây là một số lỗi tôi từng gặp, cách nhận diện và khắc phục nhanh.

No local changes to save

Đây là lỗi “không phải lỗi” phổ biến nhất. Nó xảy ra khi bạn chạy git stash trên một thư mục làm việc sạch, nơi không có tệp đã theo dõi nào được chỉnh sửa hoặc đã stage.

Để khắc phục, chạy git status, và nếu không có gì hiển thị thì không có gì để stash.

Cách giải quyết "No local changes to save" trong git stash.

Xung đột khi áp dụng một stash

Xung đột xảy ra khi nhánh bạn đang ở đã thay đổi cùng những dòng mã tồn tại trong stash của bạn. Ví dụ, khi bạn chạy git stash pop trên nhánh mới sau khi đã chỉnh sửa tệp, bạn có thể sẽ nhận thông báo lỗi:

Xung đột hợp nhất khi áp dụng một stash.

Bạn có thể thấy các dấu mốc xung đột bên trong tệp:

Dấu mốc xung đột trong tệp chưa theo dõi.

Để khắc phục, bạn có thể thực hiện bất kỳ điều nào sau đây:

  • Giải quyết xung đột thủ công trong tệp
  • Stage các tệp đã giải quyết
git add data_pipeline.py
  • Xóa stash thủ công bằng git stash drop (nếu nó KHÔNG bị xóa tự động khi có xung đột)

Nếu xung đột quá rối rắm, hãy dùng lệnh dưới đây để áp dụng thay đổi trên một nền sạch thay vào đó.

git stash branch recovery-branch stash@{0}

Lỡ stash những tệp bạn không định stash

Đôi khi bạn chạy git stash mà không kiểm tra thư mục làm việc, để rồi sau đó mới nhận ra bạn đã cất đi một bản sửa mà thực ra bạn muốn commit.

Để tránh sai sót như vậy, hãy luôn chỉ rõ các tệp cần stash. Ví dụ, lệnh dưới đây sẽ chỉ stash tệp data_pipeline.py thay vì mọi thứ trong thư mục làm việc.

git stash push data_pipeline.py

Bạn cũng có thể dùng git stash -p để chạy chế độ tương tác (patch), cho phép bạn stash có chọn lọc các phần thay đổi trong tệp, không phải cả tệp.

Như một biện pháp phòng ngừa, hãy luôn kiểm tra git status trước khi stash.

Kết luận

Theo nguyên tắc, hãy giữ các stash tồn tại ngắn hạn và luôn dùng thông điệp mô tả. Nếu bạn sẽ không quay lại công việc trong vòng một ngày, tạo một nhánh WIP sẽ an toàn hơn vì có thể push lên remote và không bị thất lạc.

Để nâng cao kỹ năng Git, tôi khuyến nghị bạn tham gia khóa Intermediate Git để học về cộng tác trong Git. Tôi cũng khuyến nghị khóa Advanced Git để học cách làm việc với Git cho các dự án lớn và xử lý các tình huống, vấn đề quản lý phiên bản phức tạp trong phát triển pipeline dữ liệu.


Allan Ouko's photo
Author
Allan Ouko
LinkedIn
Biên tập viên kỹ thuật về Khoa học dữ liệu với kinh nghiệm thực tế trong phân tích dữ liệu, trí tuệ doanh nghiệp và khoa học dữ liệu. Tôi viết nội dung thực tiễn, tập trung vào ngành về SQL, Python, Power BI, Databricks và kỹ thuật dữ liệu, dựa trên công việc phân tích trong thế giới thực. Bài viết của tôi kết nối chiều sâu kỹ thuật với tác động kinh doanh, giúp các chuyên gia chuyển đổi dữ liệu thành những quyết định vững chắc.

Câu hỏi thường gặp về Git Stash

Git stash có lưu các tệp chưa theo dõi không?

Không, theo mặc định, git stash chỉ lưu các tệp đã theo dõi. Để bao gồm tệp chưa theo dõi, hãy dùng git stash -u.

Git stash có ảnh hưởng đến lịch sử commit của tôi không?

Không, các stash tách biệt với lịch sử commit của bạn và không xuất hiện trong nhật ký của nhánh.

Sự khác nhau giữa git stash pop và git stash apply là gì?

git stash pop áp dụng stash và xóa nó, trong khi git stash apply áp dụng stash nhưng giữ nó trong danh sách stash.

Vì sao Git báo “No local changes to save”?

Vấn đề này xảy ra khi thư mục làm việc của bạn sạch, không có tệp đã theo dõi nào được chỉnh sửa hoặc đã stage để stash.

Nguyên nhân gây xung đột khi khôi phục một stash là gì?

Xung đột xảy ra khi cùng một phần của tệp đã bị thay đổi cả ở nhánh hiện tại và trong các thay đổi được stash.

Chủ đề
Git

Học Git với DataCamp

Khóa học

Git nâng cao

2 giờ
44.2K
Khám phá các nhánh và kho lưu trữ từ xa để kiểm soát phiên bản trong các dự án phần mềm và dữ liệu cộng tác bằng Git!
Xem chi tiếtBắt Đầu Khóa Học

Tạo tài khoản miễn phí của bạn

Luyện tập và Lộ trình tiến trình của bạn.

Tiếp Tục Với Google
Bằng cách tiếp tục, bạn chấp nhận Điều khoản sử dụng, Chính sách bảo mật và việc dữ liệu của bạn được lưu trữ tại Hoa Kỳ.
Xem thêm
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem thêm